package com.zh.modules.app.utils;

import com.alibaba.fastjson.JSON;
import com.zh.common.utils.Constants;
import com.zh.modules.app.entity.UserDO;
import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Objects;

/**
 * jwt工具类
 */
public class JwtUtils {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private static long expire = 604800l;

    private final static String cookieName = "token";
    /**
     * 私钥
     */
    private static final String secret = "f4e2e52034348f86b67cde581c0f9eb5";


    public static String getToken() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String tokenHeader = request.getHeader(Constants.AUTHORIZATION);
        String token = request.getParameter(Constants.AUTHORIZATION);

        if (!StringUtils.hasText(token) && !StringUtils.hasText(tokenHeader)) {
            return null;
        }

        token = StringUtils.hasText(tokenHeader) ? tokenHeader : token;
        if (!token.startsWith(Constants.AUTHORIZATION_PRE)) {
            return null;
        }
        return token.substring(Constants.AUTHORIZATION_PRE.length());
    }


    /**
     * 生成jwt token
     */
    public static String generateToken(UserDO userDO) {
        return Jwts.builder().setSubject(String.valueOf(userDO.getId())).claim("userId", userDO.getId()).claim("user", userDO).setIssuedAt(new Date())
                /*过期时间*/.setExpiration(new Date(System.currentTimeMillis() + expire * 1000)).signWith(SignatureAlgorithm.HS256, secret).compact();
    }

    public static UserDO getUser() {
        String tokenString = getToken();
        try {
            return getUser(tokenString);
        } catch (Exception e) {
            return null;
        }
    }

    public static UserDO getUser(String token) {
        final Claims claims = getClaimsFromToken(token);
        return JSON.parseObject(JSON.toJSONString(claims.get("user")), UserDO.class);
    }

    /***
     * 解析token 信息
     * @param token
     * @return
     */
    private static Claims getClaimsFromToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException e) {
            claims = e.getClaims();
        }
        return claims;
    }


    public static String getTokenByCookie() {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        return getToken(request);
    }

    private static String getToken(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null) {
            return null;
        }
        for (Cookie cookie : cookies) {
            if (cookieName.equals(cookie.getName())) {
                return cookie.getValue();
            }
        }
        return null;
    }


    public static Boolean verify(String token) {
        JwtParser jwtParser = Jwts.parser();
        try {
            jwtParser.setSigningKey(secret).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * token是否过期
     *
     * @return true：过期
     */
    public boolean isTokenExpired(Date expiration) {
        return expiration.before(new Date());
    }

}
